package com.android.common.utils.media.screen;

import android.app.Activity;
import android.content.Context;
import android.content.Intent;
import android.hardware.display.DisplayManager;
import android.hardware.display.VirtualDisplay;
import android.media.MediaRecorder;
import android.media.projection.MediaProjection;
import android.media.projection.MediaProjectionManager;
import android.util.Log;
import android.widget.Toast;
import com.android.common.R;
import com.android.common.mvp.view.ActResultCallback;
import com.android.common.mvp.view.ActResultRequest;
import com.android.common.utils.DisplayUtil;
import com.android.common.utils.FileUtil;

public class RecordScreenUtil {

    private Activity mActivity;

    private MediaProjectionManager mManager;

    private MediaProjection mMediaProjection;

    private MediaRecorder mMediaRecorder;

    private VirtualDisplay mVirtualDisplay;
    /**
     * 录屏存放路径
     */
    private String mRecordScreenPath;
    /**
     * 正在录屏
     */
    private boolean mIsScreenRecording;
    /**
     * 屏幕宽
     */
    private int mWidth;
    /**
     * 屏幕高
     */
    private int mHeight;
    /**
     * 屏幕Dpi
     */
    private int mDensityDpi = DisplayUtil.getDensityDpi();

    /**
     * 实例
     */
    private static RecordScreenUtil mInstance;

    private RecordScreenUtil(Activity activity) {
        mActivity = activity;
        mWidth = DisplayUtil.getRealScreenSize(mActivity).x;
        mHeight = DisplayUtil.getRealScreenSize(mActivity).y;
        Log.d("bonc", "createMediaRecorder 2" + "---" + mWidth + "---" + mHeight);
    }

    public static RecordScreenUtil getInstance(Activity activity) {
        if (mInstance == null) {
            mInstance = new RecordScreenUtil(activity);
        }
        return mInstance;
    }


    private MediaProjectionManager createProjectionManager() {
        if (null == mManager) {
            mManager = (MediaProjectionManager) mActivity.getSystemService(Context.MEDIA_PROJECTION_SERVICE);
        }
        return mManager;
    }

    /**
     * 创建MediaProjection
     */
    private void createMediaProjection(int resultCode, Intent data) {
        if (resultCode == Activity.RESULT_OK) {
            mMediaProjection = createProjectionManager().getMediaProjection(resultCode, data);
        }
    }

    /**
     * 创建录制
     */
    private void createMediaRecorder() {
        mRecordScreenPath = FileUtil.getRecordScreenPath(mActivity);
//        mRecordScreenPath = mActivity.getExternalFilesDir(null).getPath() + File.separator + FileUtil.getFileNameByTime("Recorder") + ".mp4";
        mMediaRecorder = new MediaRecorder();
        mMediaRecorder.setAudioSource(MediaRecorder.AudioSource.DEFAULT);
        mMediaRecorder.setVideoSource(MediaRecorder.VideoSource.SURFACE);
        mMediaRecorder.setOutputFormat(MediaRecorder.OutputFormat.MPEG_4);
        mMediaRecorder.setAudioEncoder(MediaRecorder.AudioEncoder.AAC);
        mMediaRecorder.setVideoEncoder(MediaRecorder.VideoEncoder.H264);
        mMediaRecorder.setVideoSize(mWidth, mHeight);
        mMediaRecorder.setVideoFrameRate(30);
        mMediaRecorder.setOutputFile(mRecordScreenPath);
        mMediaRecorder.setVideoEncodingBitRate(5 * mWidth * mHeight);
        mMediaRecorder.setOnErrorListener((mr, what, extra) -> {
            Toast.makeText(mActivity, mActivity.getString(R.string.screen_record_fail), Toast.LENGTH_SHORT).show();
        });

        try {
            mMediaRecorder.prepare();
        } catch (Exception e) {
            Toast.makeText(mActivity, mActivity.getString(R.string.screen_record_fail), Toast.LENGTH_SHORT).show();
            e.printStackTrace();
        }
    }

    /**
     * 创建VirtualDisplay
     */
    private void createVirtualDisplay() {
        if (mVirtualDisplay == null) {
            mVirtualDisplay = mMediaProjection.createVirtualDisplay("MediaRecorder",
                    mWidth, mHeight, mDensityDpi, DisplayManager.VIRTUAL_DISPLAY_FLAG_AUTO_MIRROR,
                    mMediaRecorder.getSurface(), null, null);
        } else {
            mVirtualDisplay.setSurface(mMediaRecorder.getSurface());
        }
    }

    private void prepareRecord() {
        createMediaRecorder();
        createVirtualDisplay();
    }

    /**
     * 开始屏幕录制
     */
    public void startCaptureRecording(int resultCode, Intent data, RecordScreenCallBack captureCallBack) {
        createMediaProjection(resultCode, data);
        if (!mIsScreenRecording && (null != mMediaProjection)) {
            prepareRecord();
            mMediaRecorder.start();
            if (captureCallBack != null) {
                captureCallBack.onStart(mRecordScreenPath);
            }
            mIsScreenRecording = true;
        } else {
            Toast.makeText(mActivity, mActivity.getString(R.string.screen_record_service_un_init), Toast.LENGTH_SHORT).show();
        }
    }

    /**
     * 停止屏幕录制
     */
    public void stopCaptureRecording(RecordScreenCallBack captureCallBack) {
        if (null != mMediaRecorder && mIsScreenRecording) {
            mMediaRecorder.stop();
            mMediaRecorder.reset();
            mMediaRecorder.release();
            mMediaRecorder = null;
            FileUtil.scanFile(mActivity, mRecordScreenPath);
        }

        if (mVirtualDisplay != null) {
            mVirtualDisplay.release();
            mVirtualDisplay = null;
        }

        if (null != captureCallBack && mIsScreenRecording) {
            captureCallBack.onSucceed(mRecordScreenPath, "");
        }

        mIsScreenRecording = false;
    }


    public void destroy() {
        stopCaptureRecording(null);
        resetMediaProjection();
        mInstance = null;
    }

    private void resetMediaProjection() {
        if (null != mMediaProjection) {
            mMediaProjection.stop();
            mMediaProjection = null;
        }
    }

    public void permissionMediaProjection(ActResultCallback scanCallback) {
        Intent intent = createProjectionManager().createScreenCaptureIntent();
        ActResultRequest actResultRequest = new ActResultRequest(mActivity);
        actResultRequest.startForResult(intent, scanCallback);
    }
}
